/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { computed, defineComponent, provide, SetupContext, onMounted, shallowRef, nextTick, ref, inject } from 'vue';
import { TabsProps, tabsProps } from '../tabs.props';
import '../tabs.css';
import { useTabs } from '../composition/use-tabs';
import { TabPageContext, TabsContext } from '../composition/types';
import getTabHeaderRender from '../components/tab-header.component';
import getTabHeaderCapsuleRender from '../components/tab-header-capsule.component';
import getMoreButtonRender from '../components/more-pages-button.component';
import { useNav } from '../composition/use-nav';
import { useDropdown } from '../composition/use-dropdown';
import { useOnePage } from '../composition/use-one-page';
import FResponseToolbar from '../../../response-toolbar/src/response-toolbar.component';
import { DesignerItemContext } from '../../../designer-canvas/src/types';
import { useDesignerComponent } from '../../../designer-canvas/src/composition/function/use-designer-component';
import { useDesignerRules } from './tab-use-designer-rules';

export default defineComponent({
    name: 'FTabsDesign',
    props: tabsProps,
    emits: ['tabChange', 'tabRemove'] as (string[] & ThisType<void>) | undefined,
    setup(props: TabsProps, context: SetupContext) {
        const elementRef = ref();
        const designItemContext = inject<DesignerItemContext>('design-item-context') as DesignerItemContext;
        const designerRulesComposition = useDesignerRules(designItemContext.schema, designItemContext.parent);
        const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition);
        const tabType = ref(props.tabType);
        // const tabsElement = shallowRef<any>();
        // 标题Ul元素
        const tabNavigationElementRef = shallowRef<any>();
        const tabContentElementRef = shallowRef<any>();

        const useTabsComposition = useTabs(props, context, tabNavigationElementRef);
        const { activeId, changeTitleStyle, tabPages, addTab, updateTab, selectTabByTabId, toolbarItems } = useTabsComposition;

        const useOnePageComposition = useOnePage(props, tabContentElementRef, useTabsComposition);

        const useNavComposition = useNav(props, tabNavigationElementRef, useOnePageComposition, useTabsComposition);
        const { previousButtonClass, nextButtonClass, nextButtonGroupClass, scrollTab, updateNavigationLayout } = useNavComposition;

        const useDropDownComposition = useDropdown(props, useTabsComposition);
        const { hideDropDown } = useDropDownComposition;

        const defaultHeaderRender = getTabHeaderRender(
            props,
            tabNavigationElementRef,
            useNavComposition,
            useOnePageComposition,
            useTabsComposition
        );

        const onePageHeaderRender = defaultHeaderRender;

        const pillsHeaderRender = getTabHeaderCapsuleRender(
            props,
            tabNavigationElementRef,
            useNavComposition,
            useOnePageComposition,
            useTabsComposition
        );

        const tabHeaderRenderMap = new Map<string, () => JSX.Element>([
            ['default', defaultHeaderRender],
            ['one-page', onePageHeaderRender],
            ['pills', pillsHeaderRender]
        ]);

        const activeTabPageSlot = computed(() => {
            const activeTabPage = tabPages.value.find((tabPage: TabPageContext) => tabPage.props.id === activeId.value);
            return activeTabPage?.slots;
        });

        const hasInHeadClass = computed(() => {
            const activeTabPage = tabPages.value.find((tabPage: TabPageContext) => tabPage.props.id === activeId.value);
            const toolbarPosition = activeTabPage?.props.toolbarPosition;
            if (toolbarPosition === 'inHead') {
                return true;
            }
            return false;
        });

        // 提供者tabs，供增加、修改tab标题用
        provide<TabsContext>('tabs', { activeId, addTab, updateTab, tabPages, tabType });
        // 填充模式
        const shouldShowNavFill = computed(() => {
            return props.fill || props.tabType === 'fill';
        });
        // 药片模式
        const shouldShowNavPills = computed(() => {
            return props.tabType === 'pills';
        });

        const tabsHeaderClass = computed(() => ({
            'farris-tabs-header': true,
            'farris-tabs-inHead': hasInHeadClass.value,
            'farris-tabs-inContent': !hasInHeadClass.value,
            'farris-tabs-nav-fill': shouldShowNavFill.value,
            'farris-tabs-nav-pills': shouldShowNavPills.value
        }));

        const tabsTitleStyle = computed(() => ({
            width: hasInHeadClass.value ? (props.titleWidth ? `${props.titleWidth}%` : '') : ''
        }));

        const tabsContainerClass = computed(() => ({
            'farris-tabs': true,
            'flex-column': props.position === 'top',
            'flex-column-reverse': props.position === 'bottom',
            'flex-row': props.position === 'left',
            'flex-row-reverse': props.position === 'right',
            'one-page': props.tabType === 'one-page'
        }));

        onMounted(() => {
            if (tabPages.value.length) {
                activeId.value = props.activeId || tabPages.value[0].props.id;
                selectTabByTabId(activeId.value);
            }
            nextTick(() => {
                updateNavigationLayout();
            });
            changeTitleStyle(tabNavigationElementRef);
            // 下拉面板之外空白处点击关闭下拉面板
            window.addEventListener('click', (ev: any) => {
                if (hideDropDown.value) {
                    return;
                }
                if (!elementRef.value?.contains(ev.target)) {
                    hideDropDown.value = true;
                }
            });
            window.addEventListener('resize', () => {
                updateNavigationLayout();
            });
            elementRef.value.componentInstance = componentInstance;
        });

        function renderPreviousButton() {
            return (
                <button
                    title="left-arrow-button"
                    type="button"
                    class={previousButtonClass.value}
                    onClick={() => {
                        scrollTab(0, -1);
                    }}></button>
            );
        }

        function renderNextButton() {
            return (
                <button
                    title="right-arrow-button"
                    type="button"
                    class={nextButtonClass.value}
                    onClick={() => {
                        scrollTab(0, 1);
                    }}></button>
            );
        }

        const { renderMorePagesButtton } = getMoreButtonRender(props, useDropDownComposition, useNavComposition, useTabsComposition);

        const onClickToolbarItem = (itemId: string) => {
            context.emit('Click', itemId);
        };

        function renderToolbar() {
            return (
                !!toolbarItems.value.length && <FResponseToolbar items={toolbarItems.value} onClick={onClickToolbarItem}></FResponseToolbar>
            );
        }

        const renderTabHeader = tabHeaderRenderMap.get(props.tabType) || tabHeaderRenderMap.get('default');

        function renderHeader() {
            return (
                <div class={tabsHeaderClass.value}>
                    <div class="farris-tabs-header-pre">{context.slots.headerPrefix?.()}</div>
                    <div class="farris-tabs-title scroll-tabs" style={tabsTitleStyle.value}>
                        {renderPreviousButton()}
                        {renderTabHeader && renderTabHeader()}
                        <div class={nextButtonGroupClass.value}>
                            {renderNextButton()}
                            {renderMorePagesButtton()}
                        </div>
                    </div>
                    {renderToolbar()}
                    <div class="farris-tabs-header-post">{context.slots.headerSuffix?.()}</div>
                </div>
            );
        }

        function renderContent() {
            return (
                <div class="farris-tabs-content" ref={tabContentElementRef}>
                    {context.slots.default?.()}
                </div>
            );
        }
        context.expose(componentInstance.value);

        return () => {
            return (
                <div class={tabsContainerClass.value} ref={elementRef}>
                    {renderHeader()}
                    {renderContent()}
                </div>
            );
        };
    }
});
